package
{
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	import flash.utils.getTimer;
	
	/* System clock and others; frequency is adjustable */
	public class Clock extends Timer
	{
		private var inittime:uint = 0;
		public var pc:uint = 0;
		private var closure:Function = function():void{};
		
		/******* Programmable Clocks *******/
		
		public function Clock(period:uint)
		{
			super(period, 0);
			addEventListener(TimerEvent.TIMER, tick);
		}

		/* Measure the actual period of this clock. */
		public function getperiod():uint {
			var time:uint = getTimer();
			return Math.round((time-inittime)/pc);  /* freq = 1/(0.001*((time-inittime)/pc)) */
		}
		
		/* Reset the counters for measuring the clock period. */
		public function clearstats():void {
			inittime = getTimer();
			pc = 0;
		}
		
		/* Change the period. */
		public function setrate(rate:uint):void {
			delay = rate;
			clearstats();
		}
		
		/* Turn clock on */
		public function on():void {
			start();
			inittime = getTimer();
		}
		
		/* Turn clock off */
		public function off():void {
			stop();
		}
		
		/* Set the output of this clock */
		public function hook(newhook:Function):void {
			closure = newhook;
		}
		
		/* What happens on each tick of clock */
		private function tick(ev:TimerEvent):void {
			pc++;
			closure.call();
		}
		
		/******* General Timing Operations *******/
		
		/* Time an operation. */
		public static function optime(op:Function):uint {
			var tx:uint = getTimer();
			op.call();
			var ty:uint = getTimer();
			return ty-tx;
		}
		
	}
}